home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / lib / c / etc / iszero.c < prev    next >
C/C++ Source or Header  |  1991-12-03  |  5KB  |  221 lines

  1. /* 
  2.  * iszero.c --
  3.  *
  4.  *    Procedure to determine whether a double is a zero, normal,
  5.  *    subnormal, etc.  This requires the number to be in IEEE format,
  6.  *    so this may end up being machine-dependent.  These routines
  7.  *    could be more efficient, but they're hardly used anyways.
  8.  *
  9.  *
  10.  * Copyright 1990 Regents of the University of California
  11.  * Permission to use, copy, modify, and distribute this
  12.  * software and its documentation for any purpose and without
  13.  * fee is hereby granted, provided that the above copyright
  14.  * notice appear in all copies.  The University of California
  15.  * makes no representations about the suitability of this
  16.  * software for any purpose.  It is provided "as is" without
  17.  * express or implied warranty.
  18.  */
  19.  
  20. #ifndef lint
  21. static char rcsid[] = "$Header: /sprite/src/lib/c/etc/RCS/iszero.c,v 1.1 91/12/02 21:48:41 kupfer Exp $ SPRITE (Berkeley)";
  22. #endif /* not lint */
  23.  
  24. #include <math.h>
  25. #include <machparam.h>
  26.  
  27. #if BYTE_ORDER == LITTLE_ENDIAN
  28. #define HIGH 1
  29. #define LOW 0
  30. #endif
  31. #if BYTE_ORDER == BIG_ENDIAN
  32. #define HIGH 0
  33. #define LOW 1
  34. #endif
  35.  
  36. #define SIGN 1
  37. #define ZEROEXP 2
  38. #define VALIDEXP 4
  39. #define HIEXP 8
  40. #define FRAC 16
  41.  
  42. #define SIGNBITS 0x80000000
  43. #define EXPBITS 0x7ff00000
  44. #define MANTBITS 0x000fffff
  45.  
  46. static int parts();
  47.  
  48. /*
  49.  *----------------------------------------------------------------------
  50.  *
  51.  * issubnormal --
  52.  *
  53.  *      Return whether a double is subnormal.
  54.  *
  55.  * Results:
  56.  *      1 if the number is subnormal, 0 otherwise.
  57.  *
  58.  * Side effects:
  59.  *      None.
  60.  *
  61.  *----------------------------------------------------------------------
  62.  */
  63. int issubnormal(value)
  64. double value;
  65. {
  66.     int result;
  67.     result = parts(value);
  68.     return (result&ZEROEXP) && (result&FRAC);
  69. }
  70.  
  71. /*
  72.  *----------------------------------------------------------------------
  73.  *
  74.  * isnormal --
  75.  *
  76.  *      Return whether a double is normal.
  77.  *
  78.  * Results:
  79.  *      1 if the number is normal, 0 otherwise.
  80.  *
  81.  * Side effects:
  82.  *      None.
  83.  *
  84.  *----------------------------------------------------------------------
  85.  */
  86. int isnormal(value)
  87. double value;
  88. {
  89.     int result;
  90.     result = parts(value);
  91.     return (result&VALIDEXP)!=0;
  92. }
  93.  
  94. /*
  95.  *----------------------------------------------------------------------
  96.  *
  97.  * iszero --
  98.  *
  99.  *      Return whether a double is zero.
  100.  *
  101.  * Results:
  102.  *      1 if the number is zero, 0 otherwise.
  103.  *
  104.  * Side effects:
  105.  *      None.
  106.  *
  107.  *----------------------------------------------------------------------
  108.  */
  109. int iszero(value)
  110. double value;
  111. {
  112.     int result;
  113.     result = parts(value);
  114.     return (result&ZEROEXP) && !(result&FRAC);
  115. }
  116.  
  117. /*
  118.  *----------------------------------------------------------------------
  119.  *
  120.  * signbit --
  121.  *
  122.  *      Return whether a double has the sign set.
  123.  *
  124.  * Results:
  125.  *      1 if the number has sign set, 0 otherwise.
  126.  *
  127.  * Side effects:
  128.  *      None.
  129.  *
  130.  *----------------------------------------------------------------------
  131.  */
  132. int signbit(value)
  133. double value;
  134. {
  135.     int result;
  136.     result = parts(value);
  137.     return (result&SIGN)!=0;
  138. }
  139.  
  140. /*
  141.  *----------------------------------------------------------------------
  142.  *
  143.  * parts --
  144.  *
  145.  *    Sets bits according to the parts of the IEEE floating point number.
  146.  *
  147.  * Results:
  148.  *    Sets SIGN if sign bit set.
  149.  *    Sets ZEROEXP if exponent is zero.
  150.  *    Sets VALIDEXP if exponent is not zero or max.
  151.  *    Sets HIEXP if exponent is max.
  152.  *    Sets FRAC if fraction is nonzero.
  153.  *
  154.  * Side effects:
  155.  *    None.
  156.  *
  157.  *----------------------------------------------------------------------
  158.  */
  159.  
  160. static int
  161. parts(value)
  162. double value;
  163. {
  164.     int result = 0;
  165.  
  166.     union {
  167.     double d;
  168.     long l[2];
  169.     } u;
  170.  
  171.     /*
  172.      * Put the value into a union so we can check out the bits.
  173.      */
  174.     u.d = value;
  175.  
  176.  
  177.     /*
  178.      * An IEEE Std 754 double precision floating point number
  179.      * has the following format:
  180.      *
  181.      *      1  bit       -- sign of Mantissa
  182.      *      11 bits      -- exponent
  183.      *      52 bits      -- Mantissa
  184.      *
  185.      * If the exponent has all bits set, the value is not a 
  186.      * real number.
  187.      *
  188.      * If the Mantissa is zero then the value is infinity, which
  189.      * is the result of division by zero, or overflow.
  190.      *
  191.      * If the Mantissa is non-zero the value is not a number (NaN).
  192.      * NaN can be generated by dividing zero by itself, taking the
  193.      * logarithm of a negative number, etc.
  194.      */
  195.  
  196.     /*
  197.      * Check the sign.
  198.      */
  199.     if (u.l[HIGH] & SIGNBITS) {
  200.     result |= SIGN;
  201.     }
  202.     /*
  203.      * check the exponent
  204.      */
  205.     if ((u.l[HIGH] & 0x7ff00000) == 0x7ff00000) {
  206.     result |= HIEXP;
  207.     } else if ((u.l[HIGH] & 0x7ff00000) == 0) {
  208.     result |= ZEROEXP;
  209.     } else {
  210.     result |= VALIDEXP;
  211.     }
  212.  
  213.     if ((u.l[HIGH] & ~0xfff00000) != 0 || u.l[LOW] != 0) {
  214.     result |= FRAC;
  215.     }
  216.  
  217.     return result;
  218. }
  219.  
  220.  
  221.